// 二分答案
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 2e5 + 10;
int p[N];
vector<vector<int>> a;
vector<vector<LL>> f;
//f[x][y] 表示：从起点(1,1)到达位置(x,y)时能够获得的最大能量值
struct Node {
  LL w;
  int x, y;
  bool operator<(const Node &o) const { return w < o.w; }
};

int n, m, K;
// 检查函数：判断给定初始能量mid是否能够从网格左上角到达右下角
// 参数mid: 初始能量值
// 返回值: 如果能够到达右下角且能量非负，返回true；否则返回false
bool check(LL mid) {
  // 初始化起点(1,1)的能量值：初始能量 + 起点收益 - 第1步代价
  f[1][1] = mid + a[1][1] - p[1];

  // 如果起点能量为负，直接返回false（无法开始移动）
  if (f[1][1] < 0)
    return false;

  // 创建优先队列（最大堆），用于存储待处理的节点
  priority_queue<Node> pq;
  // 将起点加入优先队列
  pq.push({f[1][1], 1, 1});

  // 优先队列处理循环
  while (!pq.empty()) {
    LL w;     // 当前节点的能量值
    int x, y; // 当前节点的坐标

    // 从优先队列中取出能量最大的节点
    w = pq.top().w;
    x = pq.top().x;
    y = pq.top().y;

    pq.pop(); // 移除已处理的节点

    // 如果到达终点(n,m)，返回true
    if (x == n && y == m)
      return true;

    // 延迟删除：如果队列中的能量值与当前记录的能量值不一致，说明该节点已被更新过，跳过
    if (w != f[x][y])
      continue;

    // 尝试向下移动
    if (x + 1 <= n) {
      // 计算移动到下方节点的能量值：当前能量 + 下方收益 - 当前步数代价
      LL new_w = f[x][y] + a[x + 1][y] - p[x + y];

      // 如果新能量非负且比当前记录的能量值更大，更新并加入队列
      if (new_w >= 0 && f[x + 1][y] < new_w) {
        f[x + 1][y] = new_w;
        pq.push({new_w, x + 1, y});
      }
    }

    // 尝试向右移动
    if (y + 1 <= m) {
      // 计算移动到右方节点的能量值：当前能量 + 右方收益 - 当前步数代价
      LL new_w = f[x][y] + a[x][y + 1] - p[x + y];

      // 如果新能量非负且比当前记录的能量值更大，更新并加入队列
      if (new_w >= 0 && f[x][y + 1] < new_w) {
        f[x][y + 1] = new_w;
        pq.push({new_w, x, y + 1});
      }
    }
  }

  // 如果循环结束仍未到达终点，检查终点是否可达且能量非负
  return f[n][m] >= 0;
};

int main() {
  scanf("%d%d", &n, &m);
  a = vector<vector<int>>(n + 7, vector<int>(m + 7));
  f = vector<vector<LL>>(n + 7, vector<LL>(m + 7, LLONG_MIN));

  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      scanf("%d", &a[i][j]);

  for (int i = 1; i < n + m; i++)
    scanf("%d", p + i);

  LL l = 0, r = 5e18;
  LL ans;
  while (l < r) {
    LL mid = (l + r) >> 1;
    if (check(mid)) {
      ans = mid;
      r = mid - 1;
    } else
      l = mid + 1;
  }
  cout << ans << "\n";

  return 0;
}